<?php
// @formatter:off
/**
 * @file WCReadRate.php
 * @author Alejandro Dario Simi
 * @date $Date: 2013-06-22 17:58:11 +0000 (Sat, 22 Jun 2013) $
 *
 * $Id: WCReadRate.php 83 2013-06-22 17:58:11Z daemonraco@gmail.com $
 * $URL: http://wcomix.googlecode.com/svn/tags/wcomix-1.0-BETA2/includes/WCReadRate.php $
 */
// @formatter:on

/**
 * @class WCReadRate
 */
class WCReadRate {
	/**
	 * @var WCReadRate
	 */
	protected static $_Instance;

	/**
	 * @var WCConnection
	 */
	protected $_db;
	/**
	 * @var string
	 */
	protected $_dbprefix;
	/**
	 * @var int
	 */
	protected $_group;
	/**
	 * @var int
	 */
	protected $_user;
	protected function __construct() {
		global $wcDatabaseAccess;
		global $wcGroup;
		global $wcUser;

		$this->_db = WCConnection::Instance();
		$this->_dbprefix = $wcDatabaseAccess["prefix"];
		$this->_group = $wcGroup;
		$this->_user = $wcUser;
	}
	public function __destruct() {
	}
	//
	// Public methods.
	public function comicRate(WCComic &$comic) {
		$out = $this->comicReadRate($comic);
		return $out["rate"];
	}
	public function comicReadRate(WCComic &$comic) {
		$out = array(
			"rate" => $comic->rate,
			"reads" => $comic->reads,
			"votes" => $comic->votes
		);

		return $out;
	}
	public function comicReads(WCComic &$comic) {
		$out = $this->comicReadRate($comic);
		return $out["reads"];
	}
	public function rate(WCComic &$comic, WCUser &$user = null) {
		$out = $this->readRate($comic, $user);
		return $out["rate"];
	}
	public function readRate(WCComic &$comic, WCUser &$user = null) {
		$out = array(
			"rate" => array(
				"rate" => false,
				"date" => false
			),
			"read" => array(
				"read" => false,
				"date" => false
			)
		);

		$group = $comic->group();
		$user = ($user === null) ? $this->_user : $user;

		if($user !== false) {
			$query = "select  crr_rate,\n";
			$query .= "        crr_rate_date,\n";
			$query .= "        crr_read,\n";
			$query .= "        crr_read_date\n";
			$query .= "from    {$this->_dbprefix}read_rates\n";
			$query .= "where   crr_user  = :user\n";
			$query .= " and    crr_group = :group\n";
			$query .= " and    crr_comic = :comic\n";
			$stmt = $this->_db->prepare(__CLASS__."::".__FUNCTION__, $query);

			$params = array(
				":user" => $user->id(),
				":group" => $group->id,
				":comic" => $comic->id
			);
			if($stmt->execute($params) && $stmt->rowCount() > 0) {
				$row = $stmt->fetch();

				$out["rate"]["rate"] = $row["crr_rate"];
				$out["rate"]["date"] = $row["crr_rate_date"];
				$out["read"]["read"] = $row["crr_read"] == "Y";
				$out["read"]["date"] = $row["crr_read_date"];
			}
		}

		return $out;
	}
	public function read(WCComic &$comic, WCUser &$user = null) {
		$out = $this->readRate($comic, $user);
		return $out["read"];
	}
	/**
	 * This method allows to set a rate to a comic.
	 *
	 * @param WCComic $comic Comic that is receiving a rate.
	 * @param int $rate Rate to set.
	 * @param WCUser $user User that is setting the rate.
	 * @return boolean Returns true when the rating was successfully updated.
	 */
	public function setRate(WCComic &$comic, $rate, WCUser &$user = null) {
		//
		// Loading global pointers.
		global $wcDefaults;
		//
		// Setting default value to be returned.
		$out = false;
		//
		// Checking that Read Only Mode is not activated.
		if(!$wcDefaults["read-only"]) {
			//
			// Selecting the group related to the rate to set.
			$group = $comic->group();
			//
			// If there's no user specified, the internal user is
			// user.
			$user = ($user === null) ? $this->_user : $user;
			//
			// At this point, there must be a user to use.
			if($user !== false) {
				//
				// Creating a statement to update the rate.
				// @{
				$stmt = null;
				$stmtId = __CLASS__."::".__FUNCTION__;
				if($this->_db->has($stmtId)) {
					$stmt = $this->_db->get($stmtId);
				} else {
					$query = "insert\n";
					$query .= "        into {$this->_dbprefix}read_rates (\n";
					$query .= "                crr_user, crr_group, crr_comic, crr_rate, crr_rate_date)\n";
					$query .= "        values (:user, :group, :comic, :rate, sysdate())\n";
					$query .= "        on duplicate key\n";
					$query .= "                update  crr_rate      = :rate,\n";
					$query .= "                        crr_rate_date = sysdate()\n";
					$stmt = $this->_db->prepare($stmtId, $query);
				}
				// @}
				//
				// Building database parameters.
				$params = array(
					":user" => $user->id(),
					":group" => $group->id,
					":comic" => $comic->id,
					":rate" => $rate
				);
				//
				// Updating rate.
				$stmt->execute($params);
				//
				// At this point, operation is considered to be a
				// success.
				$out = true;
			}
		}
		//
		// Returning update status.
		return $out;
	}
	/**
	 * This method allows to set a rate to a comic.
	 *
	 * @param WCComic $comic Comic which read status is changing.
	 * @param boolean $read Read status to set.
	 * @param WCUser $user User that is setting the read status.
	 * @return boolean Returns true when the read status was successfully
	 * updated.
	 */
	public function setRead(WCComic &$comic, $read = true, WCUser &$user = null) {
		//
		// Loading global pointers.
		global $wcDefaults;
		//
		// Setting default value to be returned.
		$out = false;
		//
		// Checking that Read Only Mode is not activated.
		if(!$wcDefaults["read-only"]) {
			//
			// Selecting the group related to the rate to set.
			$group = $comic->group();
			//
			// If there's no user specified, the internal user is
			// user.
			$user = ($user === null) ? $this->_user : $user;
			//
			// Since read status is a boolean, it must be transformed
			// into a valid string value.
			$crrRead = $read ? "Y" : "N";
			//
			// At this point, there must be a user to use.
			if($user !== false) {
				//
				// Creating a statement to update the read status.
				// @{
				$stmt = null;
				$stmtId = __CLASS__."::".__FUNCTION__;
				if($this->_db->has($stmtId)) {
					$stmt = $this->_db->get($stmtId);
				} else {
					$query = "insert\n";
					$query .= "        into {$this->_dbprefix}read_rates (\n";
					$query .= "                crr_user, crr_group, crr_comic, crr_read, crr_read_date)\n";
					$query .= "        values (:user, :group, :comic, :read, sysdate())\n";
					$query .= "        on duplicate key\n";
					$query .= "                update  crr_read      = :read,\n";
					$query .= "                        crr_read_date = sysdate()\n";
					$stmt = $this->_db->prepare($stmtId, $query);
				}
				// @}
				//
				// Building database parameters.
				$params = array(
					":user" => $user->id(),
					":group" => $group->id,
					":comic" => $comic->id,
					":read" => $crrRead
				);
				//
				// Updating rate.
				$stmt->execute($params);
				//
				// At this point, operation is considered to be a
				// success.
				$out = true;
			}
		}
		//
		// Returning update status.
		return $out;
	}
	/**
	 * This method allows to update statistics for all those comics that were
	 * which read status changed and those that have received a rate.
	 *
	 * @return int Returns the amount of comics updated.
	 */
	public function updateStats() {
		//
		// Loading global pointers.
		global $wcDefaults;
		//
		// Setting default value to be returned.
		$out = 0;
		//
		// Checking that Read Only Mode is not activated.
		if(!$wcDefaults["read-only"]) {
			//
			// Creating a statement to update statistics.
			// @{
			$stmt = null;
			$stmtId = __CLASS__."::".__FUNCTION__;
			if($this->_db->has($stmtId)) {
				$stmt = $this->_db->get($stmtId);
			} else {
				$query = "update  {$this->_dbprefix}comics\n";
				$query .= "set     cmc_reads = (\n";
				$query .= "                select  count(1)\n";
				$query .= "                from    {$this->_dbprefix}read_rates\n";
				$query .= "                where   crr_group     = cmc_group\n";
				$query .= "                 and    crr_comic     = cmc_id\n";
				$query .= "                 and    crr_read      = 'Y'),\n";
				$query .= "        cmc_rate  = (\n";
				$query .= "                select  avg(crr_rate)\n";
				$query .= "                from    {$this->_dbprefix}read_rates\n";
				$query .= "                where   crr_group     = cmc_group\n";
				$query .= "                 and    crr_comic     = cmc_id),\n";
				$query .= "        cmc_votes = (\n";
				$query .= "                select  count(*)\n";
				$query .= "                from    {$this->_dbprefix}read_rates\n";
				$query .= "                where   crr_group     = cmc_group\n";
				$query .= "                 and    crr_comic     = cmc_id),\n";
				$query .= "        cmc_rated = 'Y'\n";
				$query .= "where   cmc_rated = 'N'\n";
				$query .= " and    cmc_lost  = 'N'\n";

				$stmt = $this->_db->prepare($stmtId, $query);
			}
			// @}
			//
			// Updating comic ratings.
			$stmt->execute();
			//
			// Getting how many comics where updated.
			$out = $stmt->rowCount();
		}
		//
		// Returning update status.
		return $out;
	}
	//
	// Public class methods.
	public static function Instance() {
		if(!isset(self::$_Instance)) {
			$c = __CLASS__;
			self::$_Instance = new $c();
		}

		return self::$_Instance;
	}
}
?>
